package justweb

import (
	"context"
	"fmt"
	"net/http"
	"sync"
	"time"
)

func (s *HttpServer) Route(method string, pattern string, handlerfunc HandlerFunc, filters ...string) error {

	return s.Handler.Route(method, pattern, handlerfunc, filters...)
}

func (s *HttpServer) Start(address string) error {
	// return http.ListenAndServe(address, nil) -- 因为s增加了serveHTTP而修改
	return http.ListenAndServe(address, s)
}

// 为server对象增加ServeHTTP方法，这样server就实现了handler接口，作为参数传递给start使用
// 这个ServeHTTP是server实现的接口，只负责接收请求，调用函数链
func (s *HttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// c := NewContext(w, r)
	c := s.ctxPool.Get().(*Context)

	defer func() {
		s.ctxPool.Put(c)
	}()

	c.Reset(w, r)
	s.root(c)
}

func (s *HttpServer) Shutdown(ctx context.Context) error {
	fmt.Println(s.Name, "shutdown ... --> ")
	time.Sleep(2 * time.Second)
	fmt.Println(s.Name, "<-- -- shutdown")
	return nil
}

// var _ http.Handler = &HttpServer{}  实现了http.Handler的接口

type HttpServer struct {
	// Name 标识字段
	Name string
	//  依赖于接口
	Handler Handler
	// filter
	root func(c *Context)

	// context对象Pool
	ctxPool sync.Pool
}

func NewServer(name string, builder ...FilterBuilder) Server {
	// s := NewHandlerBaseOnMap()
	s := NewTreeRouter()
	var f Filter = s.ServeHTTP

	for i := len(builder) - 1; i >= 0; i-- {
		b := builder[i]
		f = b(f) // builder的参数就是Filter——也就是func(c *context)
	}
	// 等循环结束，一整条链就已经完成——filter1 > filter2 > filter3 > serveHTTP

	return &HttpServer{
		Name:    name,
		Handler: s,
		root:    f, // 责任链调用链条
		ctxPool: sync.Pool{New: func() interface{} {
			return newContextToPool()
		}},
	}
}

// 通过名字构造带中间件的Server
func NewServerWithFilterName(name string, builderName ...string) Server {
	bNames := GetMoreFilterBuilders(builderName...)
	return NewServer(name, bNames...)
}

var _ Server = &HttpServer{}
